package net.homeip.jcperera.nu.core.msg;

import java.util.logging.Level;

import net.homeip.jcperera.nu.core.CoreBase;
import net.homeip.jcperera.nu.core.boot.Boot;
import net.homeip.jcperera.nu.core.utils.ReflectionUtils;

/**
 * This is a very basic utility class and as such, it does not even conforms to the {@link CoreBase} interface. Provides
 * logging for many levels and also automatically takes care of method detection and also puts information from caller's
 * class via the reflection API.
 * 
 * @name Logger class
 * @author julio.c.perera@gmail.com
 * @application nu
 * @since 0.1.0.0
 */
public class Logger
{
    private String name = "";

    protected Logger(String name)
    {
        this.name = name;
    }

    public static Logger getLogger()
    {
        String name = ReflectionUtils.getClassNameForCaller(1);
        return getLogger(name);
    }

    public static Logger getLogger(String name)
    {
        return new Logger(name);
    }

    public static void configReload()
    {
        // TODO: Reload Log Configuration from Cache due to reset or first initialization
    }

    public void debug(String arg0)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.FINE, arg0);
    }

    public void debug(String arg0, Object param)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.FINE, arg0, param);
    }

    public void debug(String arg0, Object[] params)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.FINE, arg0, params);
    }

    public void error(String arg0)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.SEVERE, arg0);
    }

    public void error(String arg0, Object param)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.SEVERE, arg0, param);
    }

    public void error(String arg0, Object[] params)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.SEVERE, arg0, params);
    }

    public void info(String arg0)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.INFO, arg0);
    }

    public void info(String arg0, Object param)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.INFO, arg0, param);
    }

    public void info(String arg0, Object[] params)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.INFO, arg0, params);
    }

    public void trace(String arg0)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.FINEST, arg0);
    }

    public void trace(String arg0, Object param)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.FINEST, arg0, param);
    }

    public void trace(String arg0, Object[] params)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.FINEST, arg0, params);
    }

    public void warn(String arg0)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.WARNING, arg0);
    }

    public void warn(String arg0, Object param)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.WARNING, arg0, param);
    }

    public void warn(String arg0, Object[] params)
    {
        arg0 = LoggingUtils.getCoreBaseInfoAsString(1) + arg0;
        log(Level.WARNING, arg0, params);
    }

    public String getName()
    {
        return name;
    }

    protected void log(Level level, String msg)
    {
        Boot.getSystem().getLogging().addLine(level,msg);
        java.util.logging.Logger.getLogger(name).log(level, msg);
    }
    
    protected void log(Level level, String msg, Object param1)
    {
        Boot.getSystem().getLogging().addLine(level,msg, param1);
        java.util.logging.Logger.getLogger(name).log(level, msg, param1);
    }
    
    protected void log(Level level, String msg, Object[] params)
    {
        Boot.getSystem().getLogging().addLine(level,msg,params);
        java.util.logging.Logger.getLogger(name).log(level, msg, params);
    }
}
